﻿using FineUICoreDesigner.Base;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.IO;
using System.Linq;

namespace FineUIDesignerVSIX.Handle
{
    public class CoreMVCFileInfo : EditFileInfo
    {
        /// <summary>
        /// 构建控制器文件的完整路径
        /// </summary>
        public string ControllerFilePath { get; set; }

        /// <summary>
        /// 构建 Controllers 文件夹的路径
        /// </summary>
        public string ControllersFolderPath { get; set; }

        public CoreMVCFileInfo(string _FilePath) : base(_FilePath)
        {
            if (!string.IsNullOrEmpty(_FilePath))
            {
                //DesignerFileName DesignerFilePath
                FindControllerFile(_FilePath);
                DesignerFileName = Path.ChangeExtension(CsFileName, ".designer.cs"); ;
                DesignerFilePath = Path.Combine(ControllersFolderPath, DesignerFileName);
                GetCSharpTree();
            }
        }

        private void FindControllerFile(string filePath)
        { // 获取 .cshtml 文件的文件名（不包含扩展名）
            string folderName = new DirectoryInfo(Path.GetDirectoryName(filePath)).Name;

            // 获取 .cshtml 文件的上级目录
            string parentDirectory = Directory.GetParent(filePath).FullName;

            // 获取上级目录的上级目录（Views 文件夹所在的目录）
            string viewsParentDirectory = Directory.GetParent(Directory.GetParent(parentDirectory).FullName).FullName;

            // 构建 Controllers 文件夹的路径
            ControllersFolderPath = Path.Combine(viewsParentDirectory, "Controllers");

            // 构建控制器文件名
            var controllerFileName = folderName + "Controller.cs";
            CsFileName = controllerFileName;

            //判断ControllersFolderPath 路径是否存在

            if (Directory.Exists(ControllersFolderPath))
            {
                //遍历 ControllersFolderPath 下所有文件和子文件夹， 找到控制器文件
                foreach (var file in Directory.EnumerateFiles(ControllersFolderPath, "*", SearchOption.AllDirectories))
                {
                    if (Path.GetFileName(file).Equals(controllerFileName, StringComparison.OrdinalIgnoreCase))
                    {
                        ControllersFolderPath = Directory.GetParent(file).FullName;
                        ControllerFilePath = file;
                        break;
                    }
                }
            }
        }

        /// <summary>
        ///
        /// </summary>
        private void GetCSharpTree()
        {
            var code = File.ReadAllText(ControllerFilePath);
            if (string.IsNullOrEmpty(code)) return;
            SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
            CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
            var firstClass = root.DescendantNodes()
                            .OfType<ClassDeclarationSyntax>()
                            .FirstOrDefault();
            if (firstClass != null)
            {
                ClassName = firstClass.Identifier.Text;
                IsPartial = firstClass.Modifiers.Any(SyntaxKind.PartialKeyword);
                NamespaceName = firstClass?.Ancestors()?
                    .OfType<NamespaceDeclarationSyntax>()?
                    .FirstOrDefault()?.Name?.ToString();
            }
        }
    }
}
